import { isObject } from "lodash-es";
import { ComponentType } from "@/seed-application/types";
import { h } from "vue";
import { EmptyComponent } from "@/components/EmptyComponent";

export class ComponentManager {
  private cache = {}
  private viewCache = {}

  constructor() {
    this.initComponents()
    this.initViewComponents()
  }

  private initComponents() {
    const modules: Record<string, any> = import.meta.glob('/src/seed-application/components/**', { eager: true });
    for(const path in modules) {
      const fileName = path.substring(path.lastIndexOf('/') + 1)
      if(['index.ts', 'index.js'].includes(fileName)) continue
      
      const ext = path.substring(path.lastIndexOf('.') + 1)
      this.cache[path.substring('/src/seed-application/components/'.length, path.length - `.${ext}`.length)] = modules[path]['default']
    }
  }

  private initViewComponents() {
    const modules: Record<string, any> = import.meta.glob('/src/views/components/**', { eager: true });
    for(const path in modules) {
      const fileName = path.substring(path.lastIndexOf('/') + 1)
      if(['index.ts', 'index.js'].includes(fileName)) continue
      
      const ext = path.substring(path.lastIndexOf('.') + 1)
      this.viewCache[path.substring('/src/views/components/'.length, path.length - `.${ext}`.length)] = modules[path]['default']
    }
  }

  public getComponent(type: ComponentType, name?: string) {
    if(!type) return LostComponent()
    if(!name) {
      const key = `${type}/Default`
      return this.viewCache[key] || this.cache[key] || LostComponent(type)
    }

    if(isObject(name)) return name

    const key = `${type}/${name}`
    return this.viewCache[key] || this.cache[key] || LostComponent(type, name)
  }
}

function LostComponent(type?: ComponentType, component?: string) {
  if(!type) return {setup: () => () => h(EmptyComponent, {description: '组件类型走丢了'})}
  if(!component) return {setup: () => () => h(EmptyComponent, {description: `【${type}】类型组件走丢了`})}
  return {setup: () => () => h(EmptyComponent, {description: `【${type}】类型组件【${component}】走丢了`})}
}